package cn.eeepay.framework.dao.wetchatPublic;

import cn.eeepay.framework.db.pagination.Page;
import cn.eeepay.framework.model.wetchatPublic.PublicAccountMsgBatchEntity;
import cn.eeepay.framework.model.wetchatPublic.PublicAccountUserTempEntity;
import cn.eeepay.framework.util.StringUtil;
import org.apache.ibatis.annotations.*;
import org.apache.ibatis.jdbc.SQL;

import java.text.MessageFormat;
import java.util.List;
import java.util.Map;

/**
 * 公众号模板消息推送批次记录表
 *
 * @author quanhz
 * @email
 * @date 2020-07-29 15:31:47
 */
public interface PublicAccountMsgBatchDao {

  @Insert(
      "INSERT INTO `public_account_msg_batch`( `push_batch_no`, `temp_id`, `msg_data`, `user_type`, `push_time`, "
          + "`effective_start_time`, `effective_end_time`, `push_status`, `operator`, `create_time`, `remark`)"
          + " VALUES ( #{info.pushBatchNo}, #{info.tempId}, #{info.msgData}, #{info.userType}, #{info.pushTime}, "
          + " #{info.effectiveStartTime}, #{info.effectiveEndTime}, #{info.pushStatus}, #{info.operator}, #{info.createTime}, #{info.remark})")
  @SelectKey(statement="select LAST_INSERT_ID()", keyProperty="info.id", before=false, resultType=Long.class)
  int save(@Param("info") PublicAccountMsgBatchEntity info);

  @Select(
      " select openid from mer_wechat_info where user_id = ( "
          + " select user_id from user_entity_info where entity_id=#{merchantNo} limit 1 "
          + " ) and public_account=#{pubAcc} limit 1")
  String getOpenIdByMerchantNo(
      @Param("merchantNo") String merchantNo, @Param("pubAcc") String pubAcc);

  @Delete("delete from public_account_msg_batch where push_batch_no=#{pushBatchNo}")
  int removeByPushBatchNo(@Param("pushBatchNo") String pushBatchNo);

  @SelectProvider(type = PublicAccountMsgBatchDao.SqlProvider.class, method = "queryPage")
  @ResultType(List.class)
  List<PublicAccountMsgBatchEntity> queryPage(
      @Param("page") Page<PublicAccountMsgBatchEntity> page,
      @Param("info") PublicAccountMsgBatchEntity info);

  @Update(
      "update public_account_msg_batch set push_status=#{preStatus} where id=#{id}")
  int updatePushStatus(
      @Param("id") Long id, @Param("preStatus") String preStatus);

  @Select(
      "SELECT"
          + " pb.*,"
          + " pt.*,"
          + " sd.sys_name userTypeName,"
          + " sd1.sys_name pushStatusName "
          + " FROM "
          + " public_account_msg_batch pb "
          + " LEFT OUTER JOIN public_account_msg_temp pt ON pb.temp_id = pt.id "
          + " LEFT OUTER JOIN sys_dict sd ON sd.sys_key = 'MSG_TO_USER_TYPE' "
          + " AND sd.sys_value = pb.user_type "
          + " LEFT OUTER JOIN sys_dict sd1 ON sd1.sys_key = 'PUB_MSG_PUSH_STATUS' "
          + " AND sd1.sys_value = pb.push_status "
          + " where pb.id=#{id} ")
  @ResultType(PublicAccountMsgBatchEntity.class)
  PublicAccountMsgBatchEntity getById(@Param("id") Long id);

  @Update(
      "update public_account_msg_batch set effective_start_time=#{info.effectiveStartTime},effective_end_time=#{info.effectiveEndTime} where id=#{info.id}")
  int updateTimeBlock(@Param("info") PublicAccountMsgBatchEntity info);

  @InsertProvider(type= PublicAccountMsgBatchDao.SqlProvider.class, method="saveBatch")
  int saveTempUser(@Param("list") List<PublicAccountUserTempEntity> list);

  @Delete("delete from public_account_user_temp where push_batch_no=#{pushBatchNo}")
  int removeTempUser(@Param("pushBatchNo") String pushBatchNo);


  @Select("select count(1) from mer_wechat_info where public_account=#{pubAcc} ")
  Integer getUserCountByPubAcc(@Param("pubAcc") String pubAcc);

  @Select("select *from public_account_msg_batch where push_batch_no=#{pushBatchNo}")
  PublicAccountMsgBatchEntity getInfoByBatchNo(@Param("pushBatchNo") String pushBatchNo);

  @Delete("delete from public_account_msg_detail where push_batch_no=#{pushBatchNo} ")
  int removePushDetail(@Param("pushBatchNo") String pushBatchNo);

  class SqlProvider {

    public String saveBatch(Map<String, Object> param){
      List<PublicAccountUserTempEntity> list = (List<PublicAccountUserTempEntity>) param.get("list");
      StringBuffer sb = new StringBuffer("INSERT INTO `public_account_user_temp`( `push_batch_no`, `openid`, `public_acc`, `create_time`) values");
      MessageFormat message = new MessageFormat("(#'{'list[{0}].pushBatchNo},#'{'list[{0}].openid},#'{'list[{0}].publicAcc},#'{'list[{0}].createTime})," );
      for(int i=0; i<list.size(); i++){
        sb.append(message.format(new Integer[]{i}));
      }
      sb.setLength(sb.length()-1);
      return sb.toString();
    }


    public String queryPage(Map<String, Object> param) {
      final PublicAccountMsgBatchEntity info = (PublicAccountMsgBatchEntity) param.get("info");
      return new SQL() {
        {
          SELECT("pb.*,pt.*,sd.sys_name userTypeName,sd1.sys_name pushStatusName");
          SELECT(
              "(select count(1) from public_account_msg_detail where push_batch_no = pb.push_batch_no and status = 1) as send");
          SELECT(
              "(select count(1) from public_account_msg_detail where push_batch_no = pb.push_batch_no and status = 0) as notSend");
          FROM("public_account_msg_batch pb");
          LEFT_OUTER_JOIN(
              "sys_dict sd on sd.sys_key='MSG_TO_USER_TYPE' and sd.sys_value=pb.user_type");
          LEFT_OUTER_JOIN(
              "sys_dict sd1 on sd1.sys_key='PUB_MSG_PUSH_STATUS' and sd1.sys_value=pb.push_status");
          LEFT_OUTER_JOIN(" public_account_msg_temp pt on pb.temp_id = pt.id");
          if (!StringUtil.isBlank(info.getTitle())) {
            WHERE(" pt.title=#{info.title}");
          }

          if (!StringUtil.isBlank(info.getUserType())) {
            WHERE("pb.user_type = #{info.userType}");
          }

          if (!StringUtil.isBlank(info.getPubAcc())) {
            WHERE("pt.pub_acc = #{info.pubAcc}");
          }
          if (info.getCreateTimeStart() != null) {
            WHERE("pb.create_time >=#{info.createTimeStart}");
          }
          if (info.getCreateTimeEnd() != null) {
            WHERE("pb.create_time <=#{info.createTimeEnd}");
          }
        }
      }.toString();
    }
  }
}
